from owlready2 import *
import types

onto_path.append('./owl')
onto = get_ontology('http://test.org/onto.owl')

class Drug(Thing):
    namespace = onto

def print_all(items, prefix='\t'):
    for item in items:
        print(prefix, item)

def create_class():
    # 也可这样写
    with onto:
        class Drug1(Thing):
            pass
    print('1. create_class')
    print('\t', Drug.iri)
    print('\t', Drug1.iri)

def create_manage_subclass():
    class DrugAssocition(Drug):
        pass
    print('2. create_manage_subclass')
    print('\tis_a: ')
    print('\t\t', DrugAssocition.is_a)
    print('\tDrug.subclasses: ')
    print_all(Drug.subclasses(), prefix='\t\t')
    print('\tDrugAssocition.ancetors: ')
    print('\t\t', DrugAssocition.ancestors())

def create_classes_dynamically():
    print('3. create classes dynamically')
    with onto:
        new_class = types.new_class('NewClassName', (Drug, ))
        print('\t', new_class)

def create_equivalent_class():
    print('4. create equivalent class')
    with onto:
        class Drug2(Thing):
            pass
        Drug2.equivalent_to.append(Drug)
        print('\tDrug2 equivalent_to:')
        print_all(Drug2.equivalent_to, prefix='\t\t')
        class Drug3(Thing):
            pass
        Drug3.INDIRECT_equivalent_to.append(Drug)
        print('\tDrug3.INDIRECT_equivalent_to:')
        print_all(Drug3.INDIRECT_equivalent_to, prefix='\t\t')
        print('\tDrug.equivalent_to:')
        print_all(Drug.equivalent_to, prefix='\t\t')
        print('\tDrug.INDIRECT_equivalent_to:')
        print_all(Drug.INDIRECT_equivalent_to, prefix='\t\t')

def create_individuals():
    with onto:
        my_drug = Drug('my_drug')
        print('5. create individuals')
        print('\t', 'my_drug.name =', my_drug.name)
        print('\t', 'my_drug.iri = ', my_drug.iri)
        unamed_drug = Drug()
        print('\t', 'unnamed_drug.name =', unamed_drug.name)
        print('\t', 'Drug instances: ')
        for i in Drug.instances(): print('\t\t', i)
        print('\t', 'same name equal: ')
        print('\t\t', Drug('my_drug3') is Drug('my_drug3'))

def query_individual_relation():
    print('6. query individual relation')
    print('\t', onto.my_drug)
    # 示例中出现但尚未实现
    # print(onto.my_drug.has_for_active_principle)
    # print(onto.my_drug.INDIRECT_has_for_active_principle)

def introspection_individuals():
    print('7. introspection individuals')
    print('\t', 'my_drug.get_properties:')
    for prop in onto.my_drug.get_properties():
        for value in prop[onto.my_drug]:
            print("\t\t.%s == %s" % (prop.python_name, value))
    print('\t', 'my_drug.get_inverse_properties:')
    for prop in onto.my_drug.get_inverse_properties():
        print('\t\t', prop)

def multi_class_individuals():
    # 另一种写法
    # class BloodBasedProduct(Thing):
    #     ontology = onto
    with onto:
        class BloodBasedProduct(Thing):
            pass
        a_blood_based_drug = Drug('a_blood_based_drug')
        # !!!owl2ready会建立Drug和BloodBasedproduct的隐藏子类
        # 该隐藏子类可见于 a_blood_based_drug.__class__但不可见于a_blood_based_drug.is_a
        a_blood_based_drug.is_a.append(BloodBasedProduct)
        print('8. multi class individual')
        print('\t', onto.a_blood_based_drug.__class__)
        print('\t', onto.my_drug.__class__)
    
def equivalent_individuals():
    print('9. equivalent individuals')
    onto.my_drug.INDIRECT_equivalent_to.append(onto.a_blood_based_drug)
    print('\t', 'onto.my_drug.equivalent_to =', onto.my_drug.equivalent_to)
    print('\t', 'onto.my_drug.INDIRECT_equivalent_to =', onto.my_drug.INDIRECT_equivalent_to)
    print('\t', 'onto.a_blood_based_drug.equivalent_to =', onto.a_blood_based_drug.equivalent_to)
    print('\t', 'onto.a_blood_based_drug.INDIRECT_equivalent_to =', onto.a_blood_based_drug.INDIRECT_equivalent_to)

def destroying_entities():
    print('10. destroying entities')
    print('\tonto.my_drug =', onto.my_drug)
    print('\tonto.a_blood_based_drug =', onto.a_blood_based_drug)
    print('\tdestroy...')
    destroy_entity(onto.a_blood_based_drug)
    print('\tonto.my_drug =', onto.my_drug)
    print('\tonto.a_blood_based_drug =', onto.a_blood_based_drug)


create_class()
create_manage_subclass()
create_classes_dynamically()
create_equivalent_class()
create_individuals()
query_individual_relation()
introspection_individuals()
multi_class_individuals()
equivalent_individuals()
destroying_entities()